package com.hkd.forum.service.impl;

import com.hkd.forum.common.AppResult;
import com.hkd.forum.common.ResultCode;
import com.hkd.forum.dao.UserMapper;
import com.hkd.forum.exception.ApplicationException;
import com.hkd.forum.model.User;
import com.hkd.forum.service.IUserService;
import com.hkd.forum.utils.MD5Util;
import com.hkd.forum.utils.StringUtil;
import com.hkd.forum.utils.UUIDUtil;
import com.hkd.forum.utils.VerifyUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

@Slf4j
@Service
public class UserServiceImpl implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public void createNormalUser(User user) {


        //1.非空校验
        if(user == null ||  StringUtil.isEmpty(user.getUsername()) ||
                            StringUtil.isEmpty(user.getNickname()) ||
                            StringUtil.isEmpty(user.getPassword()) ||
                            StringUtil.isEmpty(user.getSalt())
        ){
            //打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            //抛出统一 ApplicationException
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        //2.非空按用户名查找
        User existsUser = userMapper.selectByUserName(user.getUsername());
        if(existsUser != null){
            log.info(ResultCode.FAILED_USER_EXISTS.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_EXISTS));
        }

        //3.设置默认值
        user.setGender((byte)2);
        user.setArticleCount(0);
        user.setIsAdmin((byte)0);
        user.setState((byte)0);
        user.setDeleteState((byte)0);
        //当前日期
        Date date = new Date();
        user.setCreateTime(date);
        user.setUpdateTime(date);

        //写入数据库
        int row = userMapper.insertSelective(user);
        if(row != 1){
            log.info(ResultCode.FAILED_CREATE.toString());

            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_CREATE));
        }

        //打印成功
        log.info("新增用户成功，userName = "+user.getUsername());
    }

    @Override
    public User selectByUserName(String username) {

        if(StringUtil.isEmpty(username)){
            //打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());

            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        return userMapper.selectByUserName(username);
    }

    @Override
    public User login(String username, String password) {
        //1.非空校验
        if(StringUtil.isEmpty(username)){
            //打印日志
            log.warn(ResultCode.FAILED_LOGIN.toString());

            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_LOGIN));
        }


        //2.按用户名查找
        User user = userMapper.selectByUserName(username);
        //3.查询结果非空校验
        if(user == null){
            //打印日志
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString() + ",user不能为空: "+ user );

            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }

        //4.密码比较
        if(!VerifyUtil.VerifyPassword(password,user.getSalt(),user.getPassword())){
            //打印日志
            log.warn(ResultCode.FAILED_LOGIN.toString() + ",密码错误 username:"+username);

            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_LOGIN));
        }
        //登陆成功
        log.info("登陆成功，username = "+username);
        return user;
    }

    @Override
    public User selectById(Long id) {
        if(id == null){
            //打印日志
            log.warn(ResultCode.ERROR_IS_NULL.toString());

            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }
        User user = userMapper.selectByPrimaryKey(id);
        return user;
    }

    @Override
    public void addOneArticleCountById(Long id) {
        //非空检验
        if(id == null || id <= 0){
            //打印日志
            log.warn(ResultCode.FAILED_BOARD_ARTICLE_COUNT.toString());
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_BOARD_ARTICLE_COUNT));
        }
        //查询用户信息
        User user = userMapper.selectByPrimaryKey(id);
        //非空校验
        if(user == null){
            //打印日志
            log.warn(ResultCode.FAILED_USER_ARTICLE_COUNT.toString());
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_ARTICLE_COUNT));
        }
        //更新用户发帖章数
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setArticleCount(user.getArticleCount() + 1);
        //调用dao执行更新
        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        //判断更新结果
        if(row != 1){
            log.warn(ResultCode.FAILED.toString() +",受影响的行数不等于一");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }
    }

    @Override
    public void subOneArticleCountById(Long id) {
        //非空检验
        if(id == null || id <= 0){
            //打印日志
            log.warn(ResultCode.FAILED_BOARD_ARTICLE_COUNT.toString());
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_BOARD_ARTICLE_COUNT));
        }
        //查询用户信息
        User user = userMapper.selectByPrimaryKey(id);
        //非空校验
        if(user == null){
            //打印日志
            log.warn(ResultCode.FAILED_USER_ARTICLE_COUNT.toString());
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_ARTICLE_COUNT));
        }
        //更新用户发帖章数
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setArticleCount(user.getArticleCount() - 1);
        //判断减一后是否小于0
        if(updateUser.getArticleCount() < 0){
            updateUser.setArticleCount(0);
        }

        //调用dao执行更新
        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        //判断更新结果
        if(row != 1){
            log.warn(ResultCode.FAILED.toString() +",受影响的行数不等于一");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }
    }

    @Override
    public void modifyInfo(User user) {
        //非空校验
        if(user == null || user.getId() == null || user.getId() <= 0){
            //打印日志
            log.warn(ResultCode.ERROR_IS_NULL.toString());
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }
        //校验用户是否存在
        User existsUser = userMapper.selectByPrimaryKey(user.getId());
        if(existsUser == null ){
            //打印日志
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString() + ",user不能为空: "+ user );
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //定义标志位
        boolean checkAttr = false;

        User updateUser = new User();
        updateUser.setId(user.getId());
        //非空属性判定
        if(!StringUtil.isEmpty(user.getUsername()) && !existsUser.getUsername().equals(user.getUsername())){
            User checkUser = userMapper.selectByUserName(user.getUsername());
            if(checkUser != null){
                //用户已存在
                log.warn(ResultCode.FAILED_USER_EXISTS.toString() + ",username: "+ user.getUsername());
                //抛出异常
                throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_EXISTS));
            }
            updateUser.setUsername(user.getUsername());
            //更新标志位
            checkAttr = true;
        }

        if(!StringUtil.isEmpty(user.getRemark()) && (existsUser.getRemark() == null || !existsUser.getRemark().equals(user.getRemark()))){
            updateUser.setRemark(user.getRemark());
            checkAttr = true;
        }
        //校验电话号
        if(!StringUtil.isEmpty(user.getPhoneNum()) && (existsUser.getPhoneNum() == null || !existsUser.getPhoneNum().equals(user.getPhoneNum()))){
            updateUser.setPhoneNum(user.getPhoneNum());
            checkAttr = true;
        }
        //校验邮箱
        if(!StringUtil.isEmpty(user.getEmail()) && (existsUser.getEmail() == null || !existsUser.getEmail().equals(user.getEmail()))){
            updateUser.setEmail(user.getEmail());
            checkAttr = true;
        }
        //校验性别
        if(user.getGender() != null && !existsUser.getGender().equals(user.getGender())){
            updateUser.setGender(user.getGender());
            //合法校验
            if(updateUser.getGender() > 2 || updateUser.getGender() < 0){
                updateUser.setGender((byte) 2);
            }
            checkAttr = true;
        }
        //校验昵称
        if(!StringUtil.isEmpty(user.getNickname()) && !existsUser.getNickname().equals(user.getNickname())){
            updateUser.setNickname(user.getNickname());
            checkAttr = true;
        }
        //根据标志位看是否执行SQL
        if(checkAttr == false){
            //打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //调用dao
        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        if(row != 1){
            log.warn(ResultCode.FAILED.toString() +",受影响的行数不等于一");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }

    }

    @Override
    public void modifyPassword(Long id, String newPassword, String oldPassword) {
        //非空校验
        if(id == null || id <= 0 || StringUtil.isEmpty(newPassword) || StringUtil.isEmpty(oldPassword)){
            //打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //查询用户信息
        User user = userMapper.selectByPrimaryKey(id);
        if(user == null || user.getDeleteState() == 1){
            //用户不存在或者已被删除
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString() + ",id: "+ id);
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //校验老密码是否正确
        if(!VerifyUtil.VerifyPassword(oldPassword , user.getSalt(), user.getPassword())){
            //打印日志
            log.warn(ResultCode.FAILED_BAD_PASSWORD.toString());
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_BAD_PASSWORD));
        }

        //生成新的盐值
        String salt = UUIDUtil.UUID_32();
        //生成新的密文
        String encryptPassword = MD5Util.md5Salt(newPassword,salt);

        //构造新对象
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setSalt(salt);//更新盐值
        updateUser.setPassword(encryptPassword);//更新密文
        Date date = new Date();
        updateUser.setUpdateTime(date);//更新时间

        //调用dao
        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        if(row != 1){
            //打印日志
            log.warn(ResultCode.FAILED.toString());
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }

    }
}
